package com.project.common.util;

import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Description: String操作的工具Class
 */
public class StringUtil {

	/** EMPTY_STRING = "" */
	public static final String EMPTY_STRING = "";

	/**
	 * Description: 判斷String是否是null或''
	 * 
	 * @param s
	 *            輸入檢查的String字符串
	 * @return 假如是null或' '，返回true；否則，返回false。
	 */
	public static boolean isNull(String s) {
		return ((s == null) || (EMPTY_STRING.equals(s.trim())));
	}

	/**
	 * Description: Eeplace specific char by specific string
	 * 
	 * @param str
	 *            the string which should be processed
	 * @param src
	 *            the replaced char
	 * @param dst
	 *            the new string
	 * @return
	 */
	public static String replace(String str, char src, String dst) {
		int strLen = str.length();
		int size = strLen + (str.length() / 20) * dst.length() + 20;

		StringBuffer sb = new StringBuffer(size);
		int offset = 0;
		int index = 0;
		while (offset < strLen
				&& (index = str.indexOf((int) src, offset)) != -1) {
			sb.append(str.substring(offset, index));
			sb.append(dst);
			offset = ++index;
		}
		if (offset < strLen)
			sb.append(str.substring(offset));
		return sb.toString();
	}

	/**
	 * Description: Replace old string by new string
	 * 
	 * @param str
	 *            the string which is processed
	 * @param src
	 *            the replaced string
	 * @param dst
	 *            the new string
	 * @return processed string
	 */
	public static String replace(String str, String src, String dst) {
		StringBuffer sb = new StringBuffer();
		int offset = 0;
		int index = 0;
		int srcLen = src.length();
		int strLen = str.length();

		while (offset < strLen && (index = str.indexOf(src, offset)) != -1) {
			sb.append(str.substring(offset, index));
			sb.append(dst);
			offset = index + srcLen;
		}
		if (offset < strLen)
			sb.append(str.substring(offset));
		return sb.toString();
	}

	/**
	 * String to Full Unicode
	 * 
	 * @param str
	 * @return
	 */
	public static String toFullUnicode(String str) {
		StringBuffer result = new StringBuffer();
		String temp = "";
		byte[] b = null;
		for (int i = 0; i < str.length(); i++) {
			temp = str.substring(i, i + 1);
			try {
				b = temp.getBytes("unicode");
			} catch (UnsupportedEncodingException e) {
				//
			}
			if (b[3] == 0) {
				if (b[2] == 32) { // Blank space
					b[2] = (byte) 0;
					b[3] = (byte) 48;
				} else { // Other 8 bit charactors
					b[2] = (byte) (b[2] - 32);
					b[3] = -1;
				}
				try {
					result.append(new String(b, "unicode"));
				} catch (UnsupportedEncodingException e) {
					//
				}
			} else {
				result.append(temp);
			}
		}
		return result.toString();
	}

	/**
	 * Description: 根據編碼規則將字符串轉換成字節串后的長度( 主要用于計算中英混合字符串長度 )
	 * 
	 * @param origin
	 *            原始字符串
	 * 
	 * @param charset
	 *            編碼規則： "UTF8", "GB18030", "GBK", "GB2312", "BIG5" 等,
	 *            如果為空，用系統默認編碼規則返回字節串長度
	 * 
	 * @return 字節串長度
	 * 
	 */
	public static int length(String origin, String charset) {
		if (StringUtil.isNull(origin)) {
			return 0;
		}
		if (StringUtil.isNull(charset)) {
			return origin.getBytes().length;
		} else {
			try {
				return origin.getBytes(charset).length;
			} catch (UnsupportedEncodingException e) {
				return 0;
			}
		}
	}

	/**
	 * Description: 根據UTF8編碼，截取指定字節長度的字符( 主要用于中英混合字符串截取 )
	 * 
	 * @param origin
	 *            原始字符串
	 * @param len
	 *            截取长度
	 * @return 返回的字符串
	 */
	public static String substringUTF8(String origin, int len) {
		if (StringUtil.isNull(origin) || len < 1) {
			return "";
		}
		try {
			byte[] originBytes = origin.getBytes("UTF-8");
			if (len > originBytes.length) {
				return origin;
			}
			int count = 0;
			for (int i = 0; i < len; i++) {
				int value = (int) originBytes[i];
				if (value < 0) {
					count++;
				}
			}
			if (count % 3 != 0 && (len > 3)) {
				while (count % 3 != 0) {
					--len;
					--count;
				}
			}
			return new String(originBytes, 0, len, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	/**
	 * 根據双字节字符集 (DBCS)編碼規則("GB18030", "GBK", "GB2312", "BIG5" 等)，截取指定字節長度的字符(
	 * 主要用于中英混合字符串截取 ).
	 * 
	 * @param origin
	 *            原始字符串
	 * @param len
	 *            截取长度
	 * @param charset
	 *            字符編碼
	 * @return 返回的字符串
	 */
	public static String substringDBCS(String origin, int len, String charset) {
		if (StringUtil.isNull(origin) || len < 1) {
			return "";
		}
		try {
			byte[] originBytes = origin.getBytes(charset);
			if (len > originBytes.length) {
				return origin;
			}
			int count = 0;
			int i = 0;
			while (i < len) {
				int value = (int) originBytes[i];
				if (value < 0) {
					count += 2;
					i += 2;
				} else {
					i++;
				}
			}
			if (i > len)
				len--;
			return new String(originBytes, 0, len, charset);
		} catch (UnsupportedEncodingException e) {
			return "";
		}
	}

	// CT_SRS_9.2.13_RMS資料匯入調帳LOG_CTCB_ZH add by lantian 2009-9-28 start
	/**
	 * 校驗字符串是否全為數字：若全為數字，則返回true；反之，返回false
	 */
	public static boolean isAllNumber(String origin) {
		boolean result = false;
		try {
			if (origin != null && !"".equals(origin)) {
				Pattern pattern = Pattern.compile("[0-9]*");
				Matcher isNum = pattern.matcher(origin);
				if (!isNum.matches()) { // 非全為數字
					result = false;
				} else { // 全為數字
					result = true;
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 判斷是否包含中文：若包含中文，則返回true；反之，返回false
	 * 
	 * @param origin
	 * @return
	 */
	public static boolean isIncludeChinese(String origin) {
		boolean result = false;
		try {
			if (origin != null && !"".equals(origin)) {
				for (int i = 0; i < origin.length(); i++) {
					String temp = origin.substring(i, i + 1);
					if (temp.matches("[\\u4E00-\\u9FA5]+")) {// 包含中文
						result = true;
						break;
					}
				}
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * description:把str中出現的0F的字符去掉
	 * 
	 * @param str
	 * @param code
	 *            編碼
	 * @return
	 */
	public static String del0F(String str, String code) {
		byte[] b1;
		try {
			b1 = str.getBytes(code);
			for (int i = 0; i < b1.length; i++) {
				if (b1[i] == 15) {
					// 假如第一個字符是0F則去掉,並重新拼接中文字
					b1 = delElement(b1, i);
					i--;
				}
			}
			return new String(b1, code);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}

	// 轉化字串為十六進位編碼
	public static String toHexString(String s) {
		String str = "";
		for (int i = 0; i < s.length(); i++) {
			int ch = (int) s.charAt(i);
			String s4 = Integer.toHexString(ch);
			str = str + s4;
		}
		return "0x" + str;// 0x表示十六進位
	}

	// 轉換十六進位編碼為字串
	public static String toStringHex(String s) {
		if ("0x".equals(s.substring(0, 2))) {
			s = s.substring(2);
		}
		byte[] baKeyword = new byte[s.length() / 2];
		for (int i = 0; i < baKeyword.length; i++) {
			try {
				baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(
						i * 2, i * 2 + 2), 16));
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		try {
			s = new String(baKeyword, "utf-8");// UTF-16le:Not
		} catch (Exception e1) {
			e1.printStackTrace();
		}
		return s;
	}

	/**
	 * description:去掉byte[]中第in位
	 * 
	 * @param b
	 * @param in
	 * @return
	 */
	public static byte[] delElement(byte[] b, int in) {
		byte[] bt = new byte[b.length - 1];
		int j = 0;
		for (int i = 0; i < b.length; i++) {
			if (i < in) {
				bt[j] = b[i];
				j++;
			} else if (i == in) {
				continue;
			} else {
				bt[j] = b[i];
				j++;
			}
		}
		return bt;
	}

	/*
	 * @param colLenght int ,欄位長度 @param possessLen int ,DB2裡中文自所佔的bytes @return
	 * String
	 */
	public static String testChinese(String orig, int colLenght, int possessLen)
			throws Exception {
		String ret = "";
		int chinese = 0;
		int ascii = 0;
		int i = 0;
		while (chinese * possessLen + ascii <= colLenght && i < orig.length()) {
			// orig.charAt(i)>255 ->chinese char or japanese char which may take
			// up more than 1 byte in DB2
			if (orig.charAt(i) > 255)
				chinese++;
			else
				ascii++;
			i++;
		}

		if (chinese * possessLen + ascii > colLenght)
			ret = orig.substring(0, chinese + ascii - 1);
		else
			ret = orig.substring(0, chinese + ascii);
		return ret;
	}

	// 判斷strs里是否存在str字符串
	public static boolean isContainStr(String[] strs, String str) {
		if (null == strs || strs.length <= 0) {
			return false;
		}
		for (String s : strs) {
			if (str.equals(s)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 截取一個帶中文字符串的欄位： 按照指定欄位長度，截取中文欄位或英文欄位信息 說明：滿足中文欄位，中英文混雜欄位，空格欄位,英文欄位，
	 * 編碼格式為MS950 例如： 異動前字符串信息(INPUT) ："7003560511000228255D220505555
	 * T歸戶S姓名姓名D121202071 持卡人 2000103112172A66666666 2 推廣員
	 * " 截取的字符串信息(OUTPUT1) ：" T歸戶S姓名姓名" 異動后字符串信息(OUTPUT2) ："D121202071 持卡人
	 * 2000103112172A66666666 2 推廣員 " 注：輸入條件為valueIndexOf=31 valueSize=15
	 * 歸戶姓名欄位說明：Start為32 End為46 Length為15
	 * 
	 * @param currentLine
	 *            異動前字符串信息
	 * @param valueIndexOf
	 *            下標的起始位置
	 * @param valueSize
	 *            欄位的長度
	 * @return nextLineBuffer 截取之後剩餘字符串（異動后字符串信息）
	 * @return result 需要截取的字符串信息
	 */

	public static String subStrMethod(String currentLine, int valueIndexOf,
			int valueSize, StringBuffer nextLineBuffer) {

		int iBef = 0;// 統計截取欄位的長度（字節為單位）
		int bef = 0;// 截取欄位結束位置的下標

		String result = "";
		String str = "";
		String nextLine = "";
		try {
			int intLen = currentLine.length();
			int ms950Len = currentLine.getBytes("ms950").length;
			// 指定編碼和未指定編碼所取出的長度不同時,代表該行有中文字
			if (intLen != ms950Len) {
				/**
				 * 把中間的中文字截取出來 1.當valueIndexOf等於零時，截取從第一位開始到最後一位結束。
				 * 2.當valueIndexOf不等於零時，截取指定的下標開始到最後一位結束。
				 */
				// 把中間的中文字截取出來,
				str = currentLine.substring(valueIndexOf);
				for (int i = 0; i < str.length(); i++) {
					/**
					 * 截取指定欄位結束位置的下標（bef） 依次取中英文字或數字，iBef會累加，
					 * 1.當為中文字有兩個字節，iBef加二。 2.當為英文或數字時有一個字節，
					 * iBef加一。直到長度等於截取欄位的長度停止累加
					 */
					if (str.substring(i, i + 1).getBytes("ms950").length != 1) {
						// 這個字為中文
						iBef += 2;
					} else {
						// 這個字為英文或數字
						iBef++;
					}
					if (iBef == valueSize) {
						// 資訊欄位已滿 （取得的長度等於截取欄位的長度）
						bef = i;
						break;
					}
				}
				// 截取中文欄位的值
				result = str.substring(0, bef + 1);
				// 截取之後剩餘字符串信息（異動後資訊字串）
				nextLine = str.substring(bef + 1);
				// 清空nextLineBuffer的值
				nextLineBuffer.delete(0, nextLineBuffer.length());
				nextLineBuffer.append(nextLine);

				// 清除下標的值
				iBef = 0;
				bef = 0;

			} else {
				// 截取英文或數字欄位的值
				result = currentLine.substring(valueIndexOf, valueIndexOf
						+ valueSize);
				nextLine = currentLine.substring(valueIndexOf + valueSize);
				// 清空nextLineBuffer的值
				nextLineBuffer.delete(0, nextLineBuffer.length());
				nextLineBuffer.append(nextLine);
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return result;

	}

	/**
	 * 依次截取多個欄位，把每個欄位以&&分隔符分開后返回，返回"欄位1&&欄位2&&欄位3......"字符串。 例如：
	 * 異動前字符串信息(INPUT)："7003560511000228255D220502222 歸戶姓名 D121202071 持卡人
	 * 2000103112172A66666666 2 推廣員 "
	 * 異動后字符串信息(OUTPUT)："700&&3560511000228255&&D220502222 && 歸戶姓名 &&D121202071
	 * && 持卡人 &&20001031&&1217&&2&&A66666666&& &&2 && 推廣員 &&"
	 * 注：輸入條件為strLine=異動前字符串信息
	 * arrList={"3","16","12","15","12","15","8","4","1","9","1","2","16"};
	 * 
	 * @param strLine
	 *            異動前字符串信息
	 * @param arrList
	 *            異動前字符串對應欄位的長度的集合
	 * @return rtn 返回"欄位1&&欄位2&&欄位3......"字符串
	 * 
	 * 
	 */
	public static String subStringForChinese(String strLine, String[] arrList) {
		int valueIndexOf = 0;

		String rtn = "";
		StringBuffer nextLineBuffer = new StringBuffer();
		/**
		 * 遞歸處理剩下的TXT中欄位 strLine當前的截取之前字符串信息 nextLineBuffer截取之後剩餘字符串信息
		 */
		for (int len = 0; len < arrList.length; len++) {
			rtn += StringUtil.subStrMethod(strLine, valueIndexOf, Integer
					.parseInt(arrList[len]), nextLineBuffer)
					+ "&&";
			strLine = nextLineBuffer.toString();
		}
		return rtn;

	}

	/**
	 * 驗證字符串的長度 strParameter: 字符串 limitLength： 長度
	 */
	public static boolean checkIdOrNote(String strParameter, int limitLength) {
		int temp_int = 0;
		byte[] b = strParameter.getBytes();
		for (int i = 0; i < b.length; i++) {
			if (b[i] >= 0) {
				temp_int = temp_int + 1;
			} else {
				temp_int = temp_int + 2;
				i++;
			}
		}
		if (temp_int > limitLength) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * @param str
	 *            所要截取的字符串
	 * @param start
	 *            要截取的起始位置
	 * @param length
	 *            要截取的長度
	 * @return
	 * @throws UnsupportedEncodingException
	 */
	public static String getSubString(String str, int start, int length)
			throws UnsupportedEncodingException {
		/**
		 * 算法邏輯部分 1.起始start所定的長度減2 2.所截取的部分length += start + 1
		 */
		start = start - 2;
		length += start + 1;
		int len = 0;
		StringBuffer sb = new StringBuffer();
		// 定義字符串的下標
		int k = 0;
		// 假如要截取的字符串長度超過綜長度,做如下處理
		if (length > str.getBytes("MS950").length) {
			// for (int i = 0; i < length - str.getBytes("MS950").length; i++) {
			str = str + "   ---error!";
			System.out.println("要截取的字符串超出總長度!返回原長度字符串!");
			// break;
			// }
			return str;
		}
		while (len < length && k < str.getBytes("MS950").length) {
			char c = str.charAt(k++);
			if (c > 255) {
				len += 2; // 中文
				if (len > length)
					break;
			} else {
				len += 1; // 英文
			}
			if (len <= start || len <= start + 1) {
				continue;
			}
			sb.append(c);
		}
		return sb.toString();
	}

	/**
	 * 半角轉全角
	 * 
	 * @param input
	 *            String.
	 * @return
	 */
	public static String ToSBC(String input) {
		char c[] = input.toCharArray();
		for (int i = 0; i < c.length; i++) {
			if (c[i] == ' ') {
				c[i] = '\u3000';
			} else if (c[i] < '\177') {
				c[i] = (char) (c[i] + 65248);

			}
		}
		return new String(c);
	}

	/**
	 * 從byte[]中截取中文字符串
	 * 
	 * @param by
	 * @param start
	 *            開始點
	 * @param end
	 *            結束點
	 * @return 字符串
	 */
	public static String subChineseWord(byte[] by, int start, int end) {
		int count = end - start;
		byte[] b = new byte[count];
		for (int i = 0; i < count; i++) {
			b[i] = by[start + i];
		}
		String s = "";
		try {
			s = new String(b, "MS950");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return s.trim();
	}

	public static boolean isNullStrings(String[] s) {
		if (null == s) {
			return true;
		}
		int len = s.length;
		if (0 == len) {
			return true;
		}
		for (String st : s) {
			if (!StringUtil.isNull(st)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 在字符串前填充指定字符以達到指定長度
	 * @param oldStr 被填充的字符串
	 * @param fillChar 填充字符
	 * @param length 指定長度
	 * @return
	 */
	public static String fillUp(String oldStr,String fillChar,int length)
	{
		if(oldStr == null || fillChar == null)
		{
			return oldStr;
		}
		if(oldStr.length()>=length)
		{
			return oldStr;
		}
		for(int i=0;i<length;i++)
		{
			oldStr = fillChar + oldStr;
			if(oldStr.length()>=length)
			{
				break;
			}
		}
		return oldStr;
		
	}
	
	/**
	 * 截取字符串
	 * @date 2011/9/2
	 * @param str
	 * @param beginIndex
	 * @param len
	 * @return
	 */
	public static String substring(String str, int beginIndex, int len){
		if(str != null && str.length()>len){
			return str.substring(beginIndex,len);
		}
		return str;
	}
	
	public static void main(String[] args) throws UnsupportedEncodingException {
		System.out.println("test:" + fillUp("1", "d", 16));

	}
	
}
